﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Diagnostics;
using System.Linq.Expressions;

namespace LinqToSQL.stuff
{
    public static class LambdaAndDelegates
    {
        public delegate int IntOperator(int param);

        static public void p()
        {
            IntOperator previousInt = new IntOperator(decrementInteger);
            IntOperator previousPreviousInt = delegate(int x)
            {
                return x - 2;
            };

            //using built in delegates
            Func<int, int> nextInt = delegate(int x)
            {
                return x + 1;
            };
            Func<int, int> cubeX = x => x * x;
            Action<int> incX = x => x++;
        }

        static public int decrementInteger(int x)
        {
            return x - 1;
        }

        static public void LambdaTest()
        {
            Func<int,int> inc = (x) => x + 1;
            Action<string> printMessage = msg => Debug.Print(msg);
            Func<int, int, bool> equal = (x, y) => x == y;

            Action sayHello = () => Debug.Print("hello world");
            //no compila porque no devuelve un valor, no puede ser una funcion
            //Func<object> sayHello2 = () => Debug.Print("hello world");

            //para que un statement del tipo Func ande hay que usar return
            Func<int,int> sayHello3 = x =>
            {
                x = x + 1;
                x = x * 2;
                return x;
            };
        }

        #region Yield Test
        static public void YieldTest()
        {
            List<int> list = new List<int>(){ 1, 2, 3, 4, 5};
            foreach (string item in list.doubleMe().stringMe())
                Debug.WriteLine(item);
            foreach (string item in list.doubleMe().stringMe().quoteMe())
                Debug.WriteLine(item);
        }

        static private IEnumerable<int> doubleMe(this IEnumerable<int> list)
        {
            foreach (int item in list)
                yield return 2 * item;
        }

        static private IEnumerable<string> stringMe(this IEnumerable<int> list)
        {
            foreach (int item in list)
                yield return item.ToString();
        }

        static private IEnumerable<string> quoteMe(this IEnumerable<string> list)
        {
            foreach (string item in list)
                yield return item.ToString();
        } 
        #endregion
    }
}
